[HBase]04 深入了解HBase架构 四

Hbase架构大全,包含组件、读写、底层原理

Posted by 李玉坤 on 2017-09-28

HBase体系结构组件

在物理上,HBase由三种服务器组成,属于主从架构。regionserver为读写提供数据。在访问数据时,客户端直接与HBase regionserver通信。region分配、DDL(创建、删除表)操作由HBase主进程处理。Zookeeper是HDFS的一部分,它的作用是维护集群的状态。

Hadoop DataNode存储Region Server的数据。所有HBase数据都存储在HDFS文件中。Region Server与HDFS datanode并置,后者为regionserver提供的数据启用数据位置(将数据放在需要的位置附近)。当HBase数据被写入时,它是本地的,但是当一个Region被移动时,在 compaction 之前它不是本地的。

NameNode维护组成文件的所有物理数据块的元数据信息。

Regions

HBase表按行键范围水平划分为“Regions”。“一个region包含表中该region的开始键和结束键之间的所有行。Region被分配给集群中的节点,称为“Region Servers”,它们为读写数据提供服务。一个region server可以服务大约1000个regions。

HBase HMaster

Region分配、DDL(创建、删除表)操作由HBase Master处理。

master 负责:

  • 协调 Region Servers
    • 在启动时分配Regions,为恢复或负载平衡重新分配Regions
    • 监控集群中的所有RegionServer实例(监听来自zookeeper的通知)
  • admin functions
    • 用于创建、删除和更新表的接口

ZooKeeper: 协调器

HBase使用ZooKeeper作为分布式协调服务来维护集群中的服务器状态。Zookeeper维护哪些服务器是存活的和可用的,并提供服务器故障通知。Zookeeper使用协商一致来保证共享状态。注意,应该有三到五台机器来达成共识。

How the Components Work Together

Zookeeper用于协调分布式系统成员的共享状态信息。RegionServer和存活的HMaster通过与ZooKeeper的会话连接。ZooKeeper通过心跳为存活会话维护临时节点。

每个RegionServer创建一个临时节点。HMaster监视这些节点以发现可用的RegionServer,它还监视这些节点以防止服务器故障。HMasters争着创建一个临时节点。Zookeeper确定第一个master并使用它来确保只有一个master是活动的。活动的HMaster将心跳发送给Zookeeper,而不活动的HMaster侦听活动HMaster失败的通知。

如果RegionServer或活动HMaster未能发送心跳信号,会话将过期,相应的临时节点将被删除。更新监听器将收到删除节点的通知。活动HMaster侦听RegionServer,并在出现故障时恢复RegionServer。不活动的HMaster侦听活动的HMaster失败,如果活动的HMaster失败,则不活动的HMaster变为活动的HMaster。

HBase First Read or Write

有一个称为META表的特殊HBase编目表,它保存集群中region的位置。ZooKeeper存储META表的位置。

客户端第一次读写HBase时发生的情况:

  • 客户端从ZooKeeper的承载META表获取RegionServer。
  • 客户机将查询. meta。服务器获取与它想要访问的行键对应的RegionServer。客户端缓存此信息和meta表位置。
  • 它将从相应的RegionServer获取行。

对于以后的读取,客户端使用缓存来检索meta位置和之前读取的行键。随着时间的推移,它不需要查询meta表,除非一个Region已经移动或者丢失,然后它将重新查询和更新缓存

HBase Meta Table

  • 这个Meta表是一个HBase表,它保存了系统中所有Region的列表。
  • .META就像一棵b树。
  • .META表结构如下:
    • key:Region start key,region id
    • values:RegionServer

Region Server Components

Region Server 运行在HDFS数据节点上,具有以下组件:

  • WAL: Write Ahead Log 是分布式文件系统中的一个文件。WAL用于存储尚未持久存储的新数据;它用于故障情况下的恢复。
  • BlockCache:是读缓存。它将频繁读取的数据存储在内存中。最近最少使用的数据在满时被清除。
  • MemStore:是写缓存。它存储尚未写入磁盘的新数据。在写入磁盘之前对其进行排序。每个Region每个列族有一个MemStore。
  • Hfiles将行存储为磁盘上已排序的键值。

HBase Write Steps (1)

当客户端发出一个Put请求时,第一步是将数据写入write-ahead日志,即WAL:

  • 编辑被附加到存储在磁盘上的WAL文件的末尾。
  • WAL用于在服务器崩溃时恢复尚未持久的数据。

HBase Write Steps (2)

一旦数据被写到WAL中,它就会被放到MemStore中。然后,put请求确认返回给客户机。

HBase MemStore

MemStore将更新作为已排序的键值存储在内存中,与存储在HFile中相同。每个列族有一个MemStore。更新按列族排序。

HBase Region Flush

当MemStore积累了足够的数据时,整个已排序的集合被写入HDFS中的新HFile。HBase为每个列族使用多个hfile,其中包含实际的单元格或键值实例。随着时间的推移,这些文件被创建为MemStores中排序的键值编辑,并作为文件刷新到磁盘。

注意,这是HBase中限制列族数量的原因之一:每个CF有一个MemStore,当一个memstore满了,所有的memstore都会发生flush。它还保存最后写入的序列号,以便系统知道到目前为止保存的是什么。

最高的序列号作为元字段存储在每个HFile中,以反映持久化的结束和继续的位置。在Region启动时,将读取序列号,并将最高的序列号用作新编辑的序列号。

HBase HFile

数据存储在一个HFile中,其中包含已排序的键/值。当MemStore积累了足够的数据时,整个排序的键值集被写入HDFS中的新HFile。这是一个顺序写。它非常快,因为它避免移动磁盘驱动器头。

HBase HFile Structure

HFile包含一个多层索引,允许HBase在不必读取整个文件的情况下查找数据。多层次的索引就像一个b+树:

  • 键值对按递增顺序存储
  • 索引按行键指向64KB“块”中的键值数据
  • 每个块都有自己的leaf-index
  • 每个块的最后一个键放在intermediate index中
  • root index指向intermediate index

trailer指向meta块,并在将数据持久化到文件的最后写入。trailer也有像Bloom过滤器和时间范围的信息。Bloom过滤器帮助跳过不包含特定行键的文件。如果文件不在读取所查找的时间范围内,则时间范围信息对于跳过该文件非常有用。

HFile Index

刚刚讨论过的索引是在打开HFile并将其保存在内存中时加载的。这允许在单个磁盘查找时执行查找。

HBase Read Merge

已经看到,与一行对应的KeyValue单元格可以位于多个位置,已经持久化的行单元格位于hfile中,最近更新的单元格位于MemStore中,最近读取的单元格位于 block cache中。因此,当您读取一行时,系统如何使相应的单元格返回?读合并键值从 block cache,MemStore,和HFiles在以下步骤:

首先,扫描器在Block cache(读缓存)中查找行单元格。最近读取的键值被缓存在这里,最近少使用的键值在需要内存时被清除。
接下来,扫描器查看MemStore,即内存中的写缓存,其中包含最近的写操作。
如果扫描程序没有找到MemStore和Block cache中的所需单元格,那么HBase将使用Block cache索引和bloom过滤器将hfile加载到内存中,内存中可能包含目标行单元格。

HBase Read Merge

如前所述,每个MemStore可能有多个hfile,这意味着在读取时可能要检查多个文件,这可能会影响性能。这叫做读放大。

HBase Minor Compaction

HBase将自动选择一些较小的hfile,并将它们重写为较大的hfile。这个过程称为小型压缩。通过将较小的文件重写为压缩后的较大的文件,执行合并排序,次要的压缩减少了存储文件的数量。

HBase Major Compaction

Major Compaction合并和重写一个Region中的所有HFile到每个列族的一个HFile中,并在此过程中删除已经被标记删除或过期的单元格。这提高了读取性能;但是,由于Major Compaction会重写所有的文件,因此在这个过程中可能会出现大量的磁盘I/O和网络流量。这叫做写放大。

可以计划自动运行Major Compaction。由于写放大,Major Compaction通常安排在周末或晚上。注意,MapR数据库已经做了改进,不需要进行压缩。Major Compaction还能够将在服务器故障或负载平衡而影响下的任何远程数据文件成为region server的本地文件。

回顾region:

  • 一个表可以水平划分为一个或多个regions。region包含开始键和结束键之间的连续、排序的行范围
  • 每个region的大小为1GB(默认)
  • 表的一个region由一个RegionServer提供给客户端
  • 一个RegionServer可以服务大约1000个Region(这些Region可能属于同一个表或不同的表)

Region Split

最初每个表有一个Region。当一个Region变得太大时,它会分裂成两个子Region。表示原始Region的一半的两个子Region在同一RegionServer上并行打开,然后将分割报告给HMaster。出于负载平衡的原因,HMaster可能会安排将新Region转移到其他服务器。

Read Load Balancing

Splitting 最初发生在同一 RegionServer 上,但是出于负载平衡的原因,HMaster可能会安排将新Region移到其他服务器上。这将导致新的RegionServer为来自远程HDFS节点的数据提供服务,直到主要的compaction将数据文件移动到RegionServer的本地节点。当HBase数据被写入时,它是本地的,但是当一个Region被移动时(为了负载平衡或恢复),它在major compaction之前都不是本地的。

HDFS Data Replication

所有的写和读都是从主节点进行的。HDFS复制WAL和HFile块。HFile块复制自动发生。HBase依赖于HDFS在存储文件时提供数据安全性。在HDFS中写入数据时,在本地写入一个副本,然后将其复制到辅助节点,然后将第三个副本写入第三个节点。

HDFS Data Replication (2)

WAL文件和Hfiles保存在磁盘上并被复制,那么HBase如何将不保存到Hfiles的MemStore更新恢复到Hfiles呢?有关答案,请参见下一节。

HBase Crash Recovery

当一个RegionServer失败时,崩溃的Region在检测和恢复步骤发生之前不可用。当失去RegionServer心跳时,Zookeeper将确定节点故障。然后,HMaster将收到RegionServer的通知。

当HMaster检测到一个RegionServer崩溃时,HMaster将这些Region从崩溃的服务器重新分配到活动的RegionServer。为了恢复崩溃RegionServer的未刷新到磁盘的memstore编辑。HMaster将属于崩溃RegionServer的WAL分割成单独的文件,并将这些文件存储在新RegionServer的数据节点中。然后,每个RegionServer从各自的分割的WAL中回放WAL,以重新构建该Region的memstore。

Data Recovery

WAL文件包含编辑列表,其中一个编辑表示单个put或delete。编辑是按时间顺序写的,因此,为了保持持久性,添加的内容被附加到存储在磁盘上的WAL文件的末尾。

如果数据仍然在内存中,而没有持久化到HFile中,那么会发生什么情况呢?WAL被重放。通过读取WAL,将包含的编辑添加到当前的MemStore并进行排序,可以完成WAL的重放。最后,MemStore被刷新写入HFile。

Apache HBase Architecture Benefits

  • Strong consistency model
    • When a write returns, all readers will see same value
  • Scales automatically
    • Regions split when data grows too large
    • Uses HDFS to spread and replicate data
  • Built-in recovery
    • Using Write Ahead Log (similar to journaling on file system)
  • Integrated with Hadoop
    • MapReduce on HBase is straightforward

HBase 调优点

- WAL关闭
- flush
- block cache: 
- memstore: size
- compact: 阀值
- split: 阀值
- balancing 
- RK:
    - 长度不建议过长
    - RK设计
        - 加timestamp
        - reverse
        - hash/md5
        - salting
        - pre-split
        ...
    - 二级索引
        Phoenix Solr ES
- TTL
- version
- compression(snappy)
- API
    put/list<put>/bulkload
    scan/get(batch/only one)
- conf
    - zk
    - retry
    - timeout
    - flush
    - compact
        - 资源消耗过大/多
            - IO资源 带宽
            Minor Compact:建议 5-6 文件
            Major Compact: 手动处理
    - split
- JVM
    - gc
    - hdfs
    - zk
- HFile 大小
    - 问题:HFile大小和HDFS block size什么关系??
    - HFile文件是否过大
        hbase.hstore.compaction.max.size = RegionSize /hbase.hstore.compactionThreshold